﻿// 
//=====================================================================================
// Repository: https://gitee.com/putzone/fofasearch
//=====================================================================================
//
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace FOFA搜索
{
    public partial class MultiSelect : UserControl
    {
        private TextBox tbSelectedValue;
        private ButtonS btnSelect; private LabelS lbGrip;
        public CheckedListBox checkListBox;
        private Label lbSelectAll; private Label lbSelectNo;
        private Form frmCheckList;

        private Panel pnlBack;
        private Panel pnlCheck;

        private Point DragOffset;

        public delegate void CheckBoxListItemClick(object sender, ItemCheckEventArgs e);
        public event CheckBoxListItemClick ItemClick;

        public MultiSelect()
        {
            Layout += new LayoutEventHandler(ComCheckBoxList_Layout);

            tbSelectedValue = new TextBox();
            tbSelectedValue.ReadOnly = true;
            tbSelectedValue.BorderStyle = BorderStyle.None;
            tbSelectedValue.BackColor = SystemColors.Window;

            btnSelect = new ButtonS();
            btnSelect.FlatStyle = FlatStyle.Flat;
            btnSelect.Click += new EventHandler(btnSelect_Click);

            lbSelectAll = new Label();
            lbSelectAll.BackColor = Color.Transparent;
            lbSelectAll.Text = "全选";
            lbSelectAll.Size = new Size(40, 20);
            lbSelectAll.ForeColor = Color.Blue;
            lbSelectAll.Cursor = Cursors.Hand;
            lbSelectAll.TextAlign = ContentAlignment.MiddleCenter;
            lbSelectAll.Click += new EventHandler(lbSelectAll_Click);

            lbSelectNo = new Label();
            lbSelectNo.BackColor = Color.Transparent;
            lbSelectNo.Text = "取消";
            lbSelectNo.Size = new Size(40, 20);
            lbSelectNo.ForeColor = Color.Blue;
            lbSelectNo.Cursor = Cursors.Hand;
            lbSelectNo.TextAlign = ContentAlignment.MiddleCenter;
            lbSelectNo.Click += new EventHandler(lbSelectNo_Click);

            checkListBox = new CheckedListBox();
            checkListBox.BorderStyle = BorderStyle.None;
            checkListBox.Location = new Point(0, 0);
            checkListBox.CheckOnClick = true;
            checkListBox.ScrollAlwaysVisible = true;
            checkListBox.LostFocus += new EventHandler(checkListBox_LostFocus);
            checkListBox.ItemCheck += new ItemCheckEventHandler(checkListBox_ItemCheck);

            frmCheckList = new Form();
            frmCheckList.FormBorderStyle = FormBorderStyle.None;
            frmCheckList.StartPosition = FormStartPosition.Manual;
            frmCheckList.ShowInTaskbar = false;

            lbGrip = new LabelS();
            lbGrip.Size = new Size(9, 18);
            lbGrip.BackColor = Color.Transparent;
            lbGrip.Cursor = Cursors.SizeNWSE;
            lbGrip.MouseDown += new MouseEventHandler(lbGrip_MouseDown);
            lbGrip.MouseMove += new MouseEventHandler(lbGrip_MouseMove);

            pnlBack = new Panel();
            pnlBack.BorderStyle = BorderStyle.FixedSingle;
            pnlBack.AutoScroll = false;

            pnlCheck = new Panel();
            pnlCheck.BorderStyle = BorderStyle.FixedSingle;

            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);

            pnlBack.Controls.Add(tbSelectedValue);
            pnlBack.Controls.Add(btnSelect);

            Controls.Add(pnlBack);

            pnlCheck.Controls.Add(checkListBox);
            pnlCheck.Controls.Add(lbSelectAll);
            pnlCheck.Controls.Add(lbSelectNo);
            pnlCheck.Controls.Add(lbGrip);
            frmCheckList.Controls.Add(pnlCheck);
        }

        private void ReloationGrip()
        {
            lbGrip.Top = frmCheckList.Height - lbGrip.Height - 1;
            lbGrip.Left = frmCheckList.Width - lbGrip.Width - 1;

            lbSelectAll.Left = 5;
            lbSelectAll.Top = frmCheckList.Height - lbSelectAll.Height;

            lbSelectNo.Left = 50;
            lbSelectNo.Top = frmCheckList.Height - lbSelectNo.Height;
        }

        private void ComCheckBoxList_Layout(object sender, LayoutEventArgs e)
        {
            Height = tbSelectedValue.Height + 6;
            pnlBack.Size = new Size(Width, Height);

            btnSelect.Size = new Size(16, Height - 6);
            btnSelect.Location = new Point(Width - btnSelect.Width - 4, 2);

            tbSelectedValue.Location = new Point(2, 2);
            tbSelectedValue.Width = Width - btnSelect.Width - 4;

            checkListBox.Height = 380;

            frmCheckList.Size = new Size(Width, checkListBox.Height);
            pnlCheck.Size = frmCheckList.Size;

            checkListBox.Width = frmCheckList.Width;
            checkListBox.Height = frmCheckList.Height - lbSelectNo.Height;

            ReloationGrip();
        }

        public void btnSelect_Click(object sender, EventArgs e)
        {
            if (frmCheckList.Visible == false)
            {
                Rectangle rec = RectangleToScreen(ClientRectangle);
                frmCheckList.Location = new Point(rec.X, rec.Y + pnlBack.Height);
                frmCheckList.Show();
                frmCheckList.BringToFront();

                ReloationGrip();
                checkListBox.LostFocus -= new EventHandler(checkListBox_LostFocus);
                checkListBox.ItemCheck -= new ItemCheckEventHandler(checkListBox_ItemCheck);

                for (int i = 0; i < checkListBox.Items.Count; i++)
                {
                    string itemName = checkListBox.Items[i].ToString();
                    if (Array.IndexOf(tbSelectedValue.Text.Split(','), itemName) != -1)
                    {
                        checkListBox.SetItemChecked(i, true);
                    }
                    else
                    {
                        checkListBox.SetItemChecked(i, false);
                    }
                }

                checkListBox.LostFocus += new EventHandler(checkListBox_LostFocus);
                checkListBox.ItemCheck += new ItemCheckEventHandler(checkListBox_ItemCheck);
            }
            else
            {
                frmCheckList.Hide();
            }
        }

        private void lbSelectAll_Click(object sender, EventArgs e)
        {
            StringBuilder sbValue = new StringBuilder();
            tbSelectedValue.Text = "";
            for (int i = 0; i < checkListBox.Items.Count; i++)
            {
                checkListBox.SetItemChecked(i, true);
                sbValue.Append(checkListBox.Items[i].ToString() + ",");
            }
            tbSelectedValue.Text = sbValue.ToString();
        }

        private void lbSelectNo_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < checkListBox.Items.Count; i++)
            {
                checkListBox.SetItemChecked(i, false);
            }
            tbSelectedValue.Text = "";
        }

        private void checkListBox_LostFocus(object sender, EventArgs e)
        {
            if (!btnSelect.RectangleToScreen(btnSelect.ClientRectangle).Contains(Cursor.Position))
            {
                frmCheckList.Hide();
                CheckedText = tbSelectedValue.Text;
            }
        }

        private void checkListBox_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (ItemClick != null)
            {
                ItemClick(sender, e);
            }
            string itemName = checkListBox.Items[e.Index].ToString();

            if (checkListBox.CheckedItems.Contains(checkListBox.Items[e.Index]))
            {

                if (e.NewValue != CheckState.Checked)
                {
                    tbSelectedValue.Text = tbSelectedValue.Text.Replace(itemName + ",", "");
                }
            }
            else
            {
                if (e.NewValue == CheckState.Checked)
                {
                    tbSelectedValue.Text += itemName + ",";
                }
            }

        }

        private void lbGrip_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int offsetX = Math.Abs(Cursor.Position.X - frmCheckList.RectangleToScreen(frmCheckList.ClientRectangle).Right);
                int offsetY = Math.Abs(Cursor.Position.Y - frmCheckList.RectangleToScreen(frmCheckList.ClientRectangle).Bottom);
                DragOffset = new Point(offsetX, offsetY);
            }
        }

        private void lbGrip_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int curWidth = Cursor.Position.X - frmCheckList.Location.X;
                int curHeight = Cursor.Position.Y - frmCheckList.Location.Y;
                if (curWidth < Width)
                {
                    curWidth = Width;
                }

                if (curHeight < checkListBox.Height)
                {
                    curHeight = checkListBox.Height;
                }

                frmCheckList.Size = new Size(Width, curHeight);
                pnlCheck.Size = frmCheckList.Size;
                checkListBox.Height = (frmCheckList.Height - lbGrip.Height) < 50 ? 50 : frmCheckList.Height - lbGrip.Height;

                ReloationGrip();
                SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
                SetStyle(ControlStyles.ResizeRedraw, true);
                SetStyle(ControlStyles.UserPaint, true);
                SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            }
        }

        public string CheckedText
        {
            get
            {
                return tbSelectedValue.Text;
            }
            set
            {
                tbSelectedValue.Text = value;
            }
        }

        public object DataSource
        {
            set
            {
                checkListBox.DataSource = value;
            }
            get
            {
                return checkListBox.DataSource;
            }
        }

        public string ValueMember
        {
            set
            {
                checkListBox.ValueMember = value;
            }
        }
        public string DisplayMember
        {
            set
            {
                checkListBox.DisplayMember = value;
            }
        }

        public int AddItems(object value)
        {
            checkListBox.Items.Add(value);
            return checkListBox.Items.Count;
        }

        public CheckedListBox.ObjectCollection Items
        {
            get
            {
                return checkListBox.Items;
            }
        }

        public string GetItemText(object item)
        {
            return checkListBox.GetItemText(item);
        }

        private void ComCheckBoxList_Load(object sender, EventArgs e)
        {

        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // MultiSelect
            // 
            this.Name = "MultiSelect";
            this.ResumeLayout(false);

        }
    }

    public class LabelS : Label
    {
        public LabelS()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            ControlPaint.DrawSizeGrip(e.Graphics, SystemColors.Window, 1, 0, Size.Width, Size.Height);
        }
    }

    public class ButtonS : Button
    {
        public ButtonS()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        }
        ButtonState state;
        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            state = ButtonState.Pushed;
            base.OnMouseDown(mevent);
        }

        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            state = ButtonState.Normal;
            base.OnMouseUp(mevent);
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);
            ControlPaint.DrawComboButton(pevent.Graphics, 0, 0, Width, Height, state);
        }

    }
}